2011年07月11日
川俣晶の縁側ソフトウェア技術雑記 total 13838 count

C# 4.0: System.Draw.Color構造体型のデフォルト引数の値をColor.Emptyにできるか?

Written By: 川俣 晶連絡先

 実につまらない場所で手が止まったのでメモ。

 C# 4.0のデフォルト引数にはどのような値でも格納できるわけではなく、メタデータに格納できる値しか入りません。実行時に確定する値は格納できません。当然、readonlyのフィールド値(例Color.Empty)も使用できません。readonlyは初期化後に変更できないだけで、初期化時に値を変更できてしまうからです。(しかも、リフレクションで強引に書き換えることまでできてしまう)

 さて問題は、System.Draw.Color構造体でEmptyの値を無効扱いしていた場合です。クラスインスタンス引数にnullを渡すのと同じように、Emptyを渡して無効を示したいわけです。しかし、構造体はnullになりません。

 しかし、構造体はdefault(T)またはnew T()を引数に渡せます。

 問題は、default(T) == new T() == Emptyかという点です。

検証プログラム §

using System;

using System.Drawing;

class Program

{

    private static void sample(string name,Color a = default(Color))

    {

        Console.WriteLine("{0} is ARGB=({1},{2},{3},{4})",name,a.A,a.R,a.G,a.B);

    }

    static void Main(string[] args)

    {

        sample("by default parameter");

        sample("by Empty parameter",Color.Empty);

        Console.WriteLine(Color.Empty == default(Color));

        Console.WriteLine(Color.Empty == new Color());

    }

}

結果 §

by default parameter is ARGB=(0,0,0,0)

by Empty parameter is ARGB=(0,0,0,0)

True

True

結論 §

 Color.Emptyとdefault(Color)またはnew Color()の値は交換可能と思って良さそうです。

感想 §

 Color.Emptyをあまりに使い慣れていたので、new Color()で同じ値が得られるとは思ってもいなかたなあ。まして、default(Color)。デフォルト引数にColor.Emptyを書こうと思わなかったら、永遠に見落としたままだったかも。考えてみればこの結果は当たり前なのだけど。